import { Table } from 'antd'
import { useState } from 'react'
import { Resizable } from 'react-resizable'

import styles from './index.module.less'

const ResizableTitle = props => {
  const { onResize, width, ...restProps } = props

  // 添加偏移量
  const [offset, setOffset] = useState(0)

  if (restProps.children[1] === '序号') {
    return <th {...restProps} />
  }
  if (!width) {
    return <th {...restProps} />
  }

  return (
    <Resizable
      // 宽度重新计算结果，表头应当加上偏移量，这样拖拽结束的时候能够计算结果；
      width={width + offset}
      height={0}
      handle={
        <button
          className='react-resizable-handle'
          // 拖拽层偏移
          style={{ transform: `translateX(${offset}px)`, zIndex: offset ? 2 : 1 }}
          onClick={e => {
            // 取消冒泡，不取消貌似容易触发排序事件
            e.stopPropagation()
            e.preventDefault()
          }}
        >
          {/* 有偏移量显示竖线 */}
          {!!offset && <span className='vernier'></span>}
        </button>
      }
      // 拖拽事件实时更新
      onResize={(e, a) => {
        // 这里只更新偏移量，数据列表其实并没有伸缩
        setOffset(a.size.width - width)
      }}
      // 拖拽结束更新
      onResizeStop={(...argu) => {
        // 拖拽结束以后偏移量归零
        setOffset(0)
        // 这里是props传进来的事件，在外部是列数据中的onHeaderCell方法提供的事件，请自行研究官方提供的案例
        onResize(...argu)
      }}
      draggableOpts={{ enableUserSelectHack: false }}
    >
      <th {...restProps} />
    </Resizable>
  )
}

const ResizableTable = ({ onResize, columns: propsColumns, ...tableProps }) => {
  const handleResize =
    index =>
    (e, { size }) => {
      onResize({
        ...propsColumns[index],
        width: size.width,
      })
    }

  // 所有列相加的宽度
  let totalColumnsWidth = propsColumns.reduce((prev, cur) => (prev += cur.width), 0)
  // 有rowSelection的时候宽度加上60
  if (tableProps.rowSelection) {
    totalColumnsWidth += 60
  }
  // 表格宽度大于所有列宽度，或者设置了高度不自适应的时候，显示横向滚动条
  const showXScroll = totalColumnsWidth > tableProps.style?.width || !tableProps.autoSizeHeight

  const columns = propsColumns.map((col, index) => ({
    ...col,
    width: showXScroll
      ? col.width
      : // 设置了宽度的按设置的展示，其他列会自动分配
        col.sysWidth,
    onHeaderCell: column => ({
      width: showXScroll ? column.width : undefined,
      fixed: column.fixed,
      onResize: handleResize(index),
    }),
  }))

  return (
    <Table
      {...tableProps}
      // 以下参数都有组件中的意义，不能被覆盖
      className={`${styles.resizableTable}`}
      components={{
        header: {
          cell: ResizableTitle,
        },
      }}
      columns={columns}
      scroll={{
        ...tableProps.scroll,
        ...{ x: showXScroll ? 'max-content' : undefined },
      }}
    />
  )
}

export default ResizableTable
